#include "implicitly.hpp"
#include "text.h"

#define WIN32_LEAN_AND_MEAN

#define fade_time 2000

#define width 400
#define height 256

imGFX* trainer;

int charSizecx;

sbutton nfoButton = {160, 80, 40, 20, false, false};
sbutton muteButton = {235, 80, 40, 20, false, false};
sbutton exitButton = {310, 80, 40, 20, false, false};

// Windows callbacks and other required functions
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND InitInstance(WNDPROC WindProc, HINSTANCE hInst);

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
	MSG msg = {0};

	HWND hWnd = InitInstance(WndProc, hInstance);

	if(hWnd == NULL)
		return 0;

	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	// now imGFX init
	imGFX tGFX(charSizecx * 82, height + 256, 0, 0);
	tGFX.Attach(hWnd);
	//trainer.ShapeWindow(IDB_TRAINER);
	tGFX.TextColor(0x00, 0x00, 0xfe);
	trainer = &tGFX;
	// end

    while(GetMessage(&msg, NULL, 0, 0)) {
        if(msg.message == WM_QUIT)
            break;
        else {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
	ExitProcess(msg.message);
}

HWND InitInstance(WNDPROC WindProc, HINSTANCE hInst) {
	WNDCLASS* wc = new WNDCLASS;
	ZeroMemory(wc, sizeof(WNDCLASS));
	wc->style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW;
	wc->hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APPLICATION));
	wc->hInstance = hInst;
	wc->lpfnWndProc = WindProc;
	wc->hCursor = LoadCursor(NULL, IDC_ARROW);
	wc->lpszClassName = TEXT("imGFX");
	wc->hbrBackground = CreateSolidBrush(0x0f0f0f);

	RegisterClass(wc);
	
	HWND hWnd = CreateWindow(wc->lpszClassName,
					        TEXT("imGFX"),
							WS_POPUP,  
							(GetSystemMetrics(SM_CXSCREEN)-width) / 2, 
							(GetSystemMetrics(SM_CYSCREEN)-height) / 2, 
							width, 
							height, 
							NULL, 
							NULL, 
							hInst, 
							NULL);

	UnregisterClass(wc->lpszClassName, hInst);
	delete wc;

	HFONT tFont = CreateFont(6, 6, 0, 0, 900, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, TEXT("Terminal"));
	SIZE charSize;

	TCHAR text = ' ';

	HDC hDC = GetDC(hWnd);
	HDC chDC = CreateCompatibleDC(hDC);
	SelectObject(chDC, tFont);

	GetTextExtentPoint32(chDC, &text, 1, &charSize);
	charSizecx = charSize.cx;

	ReleaseDC(hWnd, hDC);
	ReleaseDC(hWnd, chDC);

	SetWindowPos(hWnd, 
				 HWND_TOP, 
				 (GetSystemMetrics(SM_CXSCREEN)-charSizecx * 82) / 2,
				 (GetSystemMetrics(SM_CYSCREEN)-height - 128) / 2,
				 charSizecx * 82,
				 height,
				 SWP_NOREPOSITION);

	DeleteObject(tFont);
	return hWnd;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch(msg) {
		case WM_CREATE:
			trainer->uTimer = SetTimer(hWnd, NULL, 5, NULL);
		case WM_PAINT:
			trainer->Clear();
			// the nfo has to be drawn first then we black the rest to cover up the nfo that
			// scroll past
			if(trainer->bNfo) {
				trainer->DrawNfo(nfo);
				trainer->Primer();
			}
			trainer->WaveBanner((trainer->dib_width - (charSizecx * 52)) / 2, 16, asciiLogo);
			trainer->ScrollText(226, szScroll);
			trainer->DrawButton(nfoButton, "nfo", 0x25, 0xf0, 0x01);
			trainer->DrawButton(muteButton, "tunes", 0x25, 0xf0, 0x01);
			trainer->DrawButton(exitButton, "exit", 0x25, 0xf0, 0x01);

			trainer->CreateRainbows();
			trainer->Update();
		case WM_COMMAND:
			switch(LOWORD(wParam)) { default: break; }
		case WM_TIMER:
			RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
			break;
		case WM_KEYDOWN:
			switch(wParam) {
			case VK_DOWN:
				if(trainer->bNfo) {
					trainer->nfo_y_off += 4;
				}
				break;
			case VK_UP:
				if(trainer->bNfo) {
					trainer->nfo_y_off -= 4;
				}
				break;
			default: break;
			}
		case WM_MOUSEMOVE:
			nfoButton.bOver = trainer->IsOver(nfoButton, lParam);
			if(!nfoButton.bOver) {
				nfoButton.bDown = false;
			}
			else if(wParam & MK_LBUTTON) {
				nfoButton.bDown = true;
			}
			muteButton.bOver = trainer->IsOver(muteButton, lParam);
			if(!muteButton.bOver) {
				muteButton.bDown = false;
			}
			else if(wParam & MK_LBUTTON) {
				muteButton.bDown = true;
			}
			exitButton.bOver = trainer->IsOver(exitButton, lParam);
			if(!exitButton.bOver) {
				exitButton.bDown = false;
			}
			else if(wParam & MK_LBUTTON) {
				exitButton.bDown = true;
			}
			break;
		case WM_LBUTTONUP:
			exitButton.bDown = false;
			muteButton.bDown = false;
			nfoButton.bDown = false;

			if(nfoButton.bOver) {
				trainer->ShowNfo();
				break;
			}
			if(muteButton.bOver) {
				break;
			}
			if(exitButton.bOver) {
				PostQuitMessage(0);
				break;
			}
			break;
		case WM_LBUTTONDOWN:
			if(nfoButton.bOver) {
				nfoButton.bDown = true;
				break;
			}
			if(muteButton.bOver) {
				muteButton.bDown = true;
				break;
			}
			if(exitButton.bOver) {
				exitButton.bDown = true;
				break;
			}
			SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
			break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}